#include "stdafx.h"
#include "bbAddon.h"


/*======================================================================*/
/*						 Event Manager */
/*======================================================================*/

/* ***********
 * PRIVATE *
 ************/

struct TEvent{
	int _id;
	int _x;
	int _y;
	int _src;
	char* _data;
	TEvent *_next;
	TEvent *_prev;
};

TEvent* __NULL_EVENT			=	new TEvent();
TEvent* __HEAD_EVENT			=	__NULL_EVENT;
TEvent* __TAIL_EVENT			=	__NULL_EVENT;

TEvent* __mCURRENTEVENT			=	__NULL_EVENT;

int __mEventStackCount			=	0;
int __mEventStackSize			=	128;
int __mEventEnableStack			=	0;


void __DeleteEvent (TEvent * ev)
{
	if (ev==__NULL_EVENT) return;
	
	if (ev==__mCURRENTEVENT) __mCURRENTEVENT=__NULL_EVENT;
	
	if (ev==__HEAD_EVENT)
	{
		if (ev==__TAIL_EVENT)
		{
			__HEAD_EVENT=__NULL_EVENT;
			__TAIL_EVENT=__NULL_EVENT;
			__mCURRENTEVENT=__NULL_EVENT;
		}
		else
		{
			__HEAD_EVENT=__HEAD_EVENT->_next;
			__HEAD_EVENT->_prev=__NULL_EVENT;
		};
	}
	else
	{
		if (ev==__TAIL_EVENT)
		{
			__TAIL_EVENT=__TAIL_EVENT->_prev;
			__TAIL_EVENT->_next=__NULL_EVENT;
		}
		else
		{
			ev->_next->_prev=ev->_prev;
			ev->_prev->_next=ev->_next;
		};
	};
	delete ev;
	__mEventStackCount--;
};

TEvent* FirstEvent(){return __HEAD_EVENT;};
TEvent* LastEvent(){return __TAIL_EVENT;};

/* ********
 * PUBLIC *
 **********/

BBAEXP void BBACALL EmitEvent(int Event_Id,int Event_X,int Event_Y,char* Event_Data,int Event_Source)
{
	TEvent* e		=	new TEvent();
	e->_id			=	Event_Id;
	e->_x			=	Event_X;
	e->_y			=	Event_Y;
	e->_data		=	Event_Data;
	e->_src			=	Event_Source;
	
	if (__HEAD_EVENT==__NULL_EVENT)
	{
		__HEAD_EVENT=	e;
		e->_prev	=	__NULL_EVENT;
	}
	else
	{
		__TAIL_EVENT->_next=e;
		e->_prev	=	__TAIL_EVENT;
	};
	__TAIL_EVENT	=	e;
	e->_next		=	__NULL_EVENT;
	__mEventStackCount		++;
};

BBAEXP int BBACALL PollEvent()
{
	// remove last interpreted event
	if (__mCURRENTEVENT!=__NULL_EVENT)
	{
		__DeleteEvent (__mCURRENTEVENT);
	};
	
	if (__HEAD_EVENT==__NULL_EVENT)	{__mEventStackCount=0;return 0;};

	if (__mEventEnableStack>0)
	{
		while(__mEventStackCount>__mEventStackSize)
		{
			if (__HEAD_EVENT==__NULL_EVENT)
			{
				__mEventStackCount=0;
				break;
			};
			__DeleteEvent (__HEAD_EVENT);
		};
	};
	
	if (__HEAD_EVENT==__NULL_EVENT)	{__mEventStackCount=0;return 0;};
	
	__mCURRENTEVENT=__HEAD_EVENT;
		
	return (__HEAD_EVENT!=__NULL_EVENT);
};


BBAEXP int BBACALL EventID()
{
	if (__mCURRENTEVENT!=__NULL_EVENT) return __mCURRENTEVENT->_id;
	return 0;
};

BBAEXP int BBACALL EventX()
{
	if (__mCURRENTEVENT!=__NULL_EVENT) return __mCURRENTEVENT->_x;
	return 0;
};

BBAEXP int BBACALL EventY()
{
	if (__mCURRENTEVENT!=__NULL_EVENT) return __mCURRENTEVENT->_y;
	return 0;
};

BBAEXP int BBACALL EventSource()
{
	if (__mCURRENTEVENT!=__NULL_EVENT) return __mCURRENTEVENT->_src;
	return 0;
};

BBAEXP char* BBACALL EventData()
{
	if (__mCURRENTEVENT!=__NULL_EVENT) return __mCURRENTEVENT->_data;
	return "";
};

BBAEXP void BBACALL EventEnableStack(int enable)
{	__mEventEnableStack=(enable!=0);
};

BBAEXP int BBACALL EventStackEnabled()
{	return (__mEventEnableStack!=0);
};

BBAEXP void BBACALL SetEventStackSize(int Size)
{
	__mEventStackSize=Size;
};

BBAEXP int BBACALL EventStackSize()
{
	return __mEventStackSize;
};

BBAEXP int BBACALL CountEvents()
{
	return __mEventStackCount;
};

